﻿namespace KinonekoSoftware.Foundation.UI.Controls
{
    public static class Xaml
    {
        public static T GetParent<T>(DependencyObject dp, int maxDepth = 32) where T : DependencyObject
        {
            var parent = VisualTreeHelper.GetParent(dp);
            var depth  = 0;
            
            while (parent is not T && depth < maxDepth)
            {
                parent = VisualTreeHelper.GetParent(parent);
                depth++;
            }


            return parent as T;
        }
        
        /// <summary>
        /// 利用visualtreehelper寻找对象的子级对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static List<T> FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
        {
            try
            {
                var TList = new List<T>(8);
                for (var i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
                {
                    var child = VisualTreeHelper.GetChild(obj, i);
                    if (child is T instance)
                    {
                        TList.Add(instance);
                        var childOfChildren = FindVisualChild<T>(child);
                        if (childOfChildren != null)
                        {
                            TList.AddRange(childOfChildren);
                        }
                    }
                    else
                    {
                        var childOfChildren = FindVisualChild<T>(child);
                        if (childOfChildren != null)
                        {
                            TList.AddRange(childOfChildren);
                        }
                    }
                }
                return TList;
            }
            catch
            {
                return null;
            }
        }

        public static List<DependencyObject> GetSubVisualTree(DependencyObject obj)
        {
            var              pending = new Queue<DependencyObject>();
            var              list    = new List<DependencyObject>(32);
            DependencyObject current;
            DependencyObject item;
            
            pending.Enqueue(obj);

            while (pending.Count > 0 && list.Count < 32)
            {
                //
                //
                current = pending.Dequeue();
                
                //
                //
                var count = VisualTreeHelper.GetChildrenCount(current);
                
                //
                //
                for (var i = 0; i < count; i++)
                {
                    item = VisualTreeHelper.GetChild(current, i);
                    
                    //
                    //
                    pending.Enqueue(item);
                    list.Add(item);
                }
            }

            return list;
        }
    }
}